﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace KD.Sms.SerialServer
{
    public class PLY650_Net : IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public PLY650_Net(string ip, int port)
        {
            E_IP = ip;
            E_Port = port;
            E_Interval = 100;
        }
        /// <summary>
        /// 当前类名
        /// </summary>
        public static string _strClassName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;

        /// <summary>
        /// 
        /// </summary>
        public string E_IP { set; get; }
        /// <summary>
        /// 
        /// </summary>
        public int E_Port { set; get; }

        public int E_Interval { set; get; }

        /// <summary>
        /// 同步返回事件
        /// </summary>
        public event EventHandler<CommonEventArgs> ReadEvent;
        /// <summary>
        /// 重量读取线程
        /// </summary>
        private Thread _thrdRead;
        /// <summary>
        /// 线程控制开关
        /// </summary>
        private bool _bRun = false;
        /// <summary>
        /// TCP客户端对象
        /// </summary>
        private TcpClient tcpClient;
        /// <summary>
        /// TCP数据操作流
        /// </summary>
        private NetworkStream ntwStream;

        /// <summary>
        /// 
        /// </summary>
        public void DoRead()
        {
            _bRun = true;
            _thrdRead = new Thread(new ThreadStart(DoReadListening));
            _thrdRead.IsBackground = true;
            _thrdRead.Start();
        }

        /// <summary>
        /// 停止光幕数据读取
        /// </summary>
        public void DoStop()
        {
            _bRun = false;
            System.Threading.Thread.Sleep(E_Interval);
            if (_thrdRead != null)
                _thrdRead.Abort();
        }
        Byte[] _bySendStart = new Byte[8];
        /// <summary>
        /// 光幕数据读取
        /// </summary>
        private void DoReadListening()
        {
            System.Threading.Thread.Sleep(1500);
            if (NetJudger.DoJudge(E_IP))
            {
                _bySendStart[0] = 0x01;
                _bySendStart[1] = 0x03;
                _bySendStart[2] = 0x10;
                _bySendStart[3] = 0x00;
                _bySendStart[4] = 0x00;
                _bySendStart[5] = 0x01;
                _bySendStart[6] = 0x80;
                _bySendStart[7] = 0xca;

                try
                {
                    tcpClient = new TcpClient();
                    tcpClient.Connect(E_IP, E_Port);
                    ntwStream = tcpClient.GetStream();
                    if (ntwStream.CanRead)
                    {
                        //接收状态,长度<1024字节
                        byte[] _byReadValue;
                        string _strReadData;
                        int byteLength;
                        string[] _arrWeight;
                        int _iWeight = 0;
                        decimal _dWeight = 0;
                        while (_bRun)
                        {
                            if (NetJudger.DoJudge(E_IP))
                            {
                                try
                                {
                                    if (ntwStream.CanWrite)
                                    {
                                        ntwStream.Write(_bySendStart, 0, _bySendStart.Length);
                                    }
                                    _byReadValue = new Byte[128];
                                    _strReadData = string.Empty;
                                    byteLength = ntwStream.Read(_byReadValue, 0, _byReadValue.Length);
                                    if (byteLength > 0)
                                    {
                                        _strReadData = "";
                                        for (int i = 0; i < _byReadValue.Length; i++)
                                        {
                                            _strReadData = _strReadData + _byReadValue[i].ToString("X").PadLeft(2, '0') + " ";
                                        }
                                        if (_strReadData.IndexOf("01 03 02", 0) >= 0)
                                        {
                                            _arrWeight = _strReadData.Split(' ');
                                            if (_arrWeight.Length > 6)
                                            {
                                                _iWeight = GetHexadecimalValue(_arrWeight[3] + _arrWeight[4]);
                                                if (_iWeight > 32767)
                                                    _iWeight = _iWeight - 65536;
                                            }

                                            _dWeight = decimal.Parse((_iWeight * 1.0 / 100).ToString("F2"));
                                            EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs(_dWeight));
                                        }
                                    }
                                    //System.Threading.Thread.Sleep(500);
                                }
                                catch (Exception ex)
                                {
                                    EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs(ex.StackTrace));
                                    Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, _strClassName, "称重仪表数据采集异常,系统尝试重连!!");
                                    Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, _strClassName, ex.ToString());
                                    if (ex.ToString().IndexOf("远程主机强迫关闭了一个现有的连接") >= 0)
                                    {
                                        System.Threading.Thread.Sleep(10000);
                                        try
                                        {
                                            ntwStream.Close();
                                            tcpClient.Close();
                                            System.Threading.Thread.Sleep(2000);

                                            tcpClient = new TcpClient();
                                            tcpClient.Connect(E_IP, E_Port);
                                            ntwStream = tcpClient.GetStream();
                                            System.Threading.Thread.Sleep(2000);
                                            Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, _strClassName, "称重仪表数据采集异常，重连成功");
                                        }
                                        catch (Exception exx)
                                        {
                                            Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, _strClassName, "称重仪表数据读取失败，系统重连出错");
                                            Log.LogHelper.DoWriteLogTypeClass(Log.LogType.Program, _strClassName, exx.ToString());
                                        }
                                    }
                                }
                            }
                            else
                                System.Threading.Thread.Sleep(500);
                            //ntwStream.Close();
                            //tcpClient.Close();
                            System.Threading.Thread.Sleep(800);
                        }
                    }
                    else
                    {
                        ntwStream.Close();
                        tcpClient.Close();
                    }
                }
                catch (Exception ex)
                {
                    EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs(ex.StackTrace));
                }
            }
            else
                EventHelper.DispatchEventAsync<CommonEventArgs>(this, this.ReadEvent, new CommonEventArgs(9999));
        }

        /// <summary>
        /// 十六进制换算为十进制
        /// </summary>
        /// <param name="strColorValue"></param>
        /// <returns></returns>
        public static int GetHexadecimalValue(String strColorValue)
        {
            char[] nums = strColorValue.ToCharArray();
            int total = 0;
            try
            {
                for (int i = 0; i < nums.Length; i++)
                {
                    String strNum = nums[i].ToString().ToUpper();
                    switch (strNum)
                    {
                        case "A":
                            strNum = "10";
                            break;
                        case "B":
                            strNum = "11";
                            break;
                        case "C":
                            strNum = "12";
                            break;
                        case "D":
                            strNum = "13";
                            break;
                        case "E":
                            strNum = "14";
                            break;
                        case "F":
                            strNum = "15";
                            break;
                        default:
                            break;
                    }
                    double power = Math.Pow(16, Convert.ToDouble(nums.Length - i - 1));
                    total += Convert.ToInt32(strNum) * Convert.ToInt32(power);
                }

            }
            catch (System.Exception ex)
            {
                String strErorr = ex.ToString();
                return 0;
            }


            return total;
        }


        #region 释放托管资源
        private bool IsDisposed = false;
        /// <summary>
        /// 释放资源
        /// </summary>
        public virtual void Dispose()
        {
            if (!this.IsDisposed)
            {
                try
                {
                    if (_thrdRead != null)
                    {
                        _bRun = false;
                        System.Threading.Thread.Sleep(200);
                        _thrdRead.Abort();
                    }
                    ntwStream.Close();
                    tcpClient.Close();
                }
                finally
                {
                    this.IsDisposed = true;
                    GC.SuppressFinalize(this);
                }
            }
        }
        #endregion


    }
}
